{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#LECL"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "import os\n",
    "\n",
    "\n",
    "from langchain.chat_models import ChatOpenAI\n",
    "\n",
    "from langchain.prompts import ChatPromptTemplate\n",
    "from langchain.schema.output_parser import StrOutputParser\n",
    "\n",
    "from operator import itemgetter\n",
    "\n",
    "from langchain.schema.runnable import RunnableMap\n",
    "\n",
    "\n",
    "from dotenv import load_dotenv, find_dotenv"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "_ = load_dotenv(find_dotenv())\n",
    "\n",
    "# 配置 OpenAI 服务\n",
    "OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')  ## 设置openai的key\n",
    "OPENAI_API_BASE = os.getenv('OPENAI_BASE_URL')  ## 更换为代理地址\n",
    "print(os.getenv(\"OPENAI_API_KEY\"))\n",
    "print(os.getenv(\"OPENAI_BASE_URL\"))\n",
    "llm = ChatOpenAI(openai_api_base=OPENAI_API_BASE, openai_api_key=OPENAI_API_KEY,\n",
    "                  temperature=0)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "#LCEL 1，一个提示词执行，提示词-模型-输出格式化\n",
    "prompt=ChatPromptTemplate.from_template(\"帮我规划一下从到{start_place}到{end_place}的出行方案\")\n",
    "# StrOutputParser()-对于输出内容进行格式化，例如\\n转换为换行\n",
    "chain=prompt|llm|StrOutputParser()\n",
    "response=chain.invoke({\"start_place\":\"烟台\",\"end_place\":\"北京\"})\n",
    "print(response)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "#LCEL 2，两个提示词一次执行，根据第一个的提示词的回答内容，执行第二个提示词\n",
    "# prompt=ChatPromptTemplate.from_template(\"帮我规划一下从到{start_place}到{end_place}的出行方案\"\n",
    "# prompt2=ChatPromptTemplate.from_template(\"从{travel_mode}中告诉我{mmthod}的出行方式？根据出行方式告诉我这种出行方式有什么危险？到了目的地后，我如何乘坐{flag}去天安门？\")\n",
    "# chain=prompt | llm | StrOutputParser()\n",
    "# #prompt2中需要传入的参数需要在chain2中用itemgetter进行定义，然后在chain2.invoke()中传入，例如flag、mmthod\n",
    "# chain2=({\"travel_mode\":chain,\"flag\":itemgetter(\"flag\"),\"mmthod\":itemgetter(\"mmthod\")}\n",
    "#         | prompt2 | llm | StrOutputParser())\n",
    "# response=chain2.invoke({\"start_place\":\"烟台\",\"end_place\":\"北京\",\"mmthod\":\"最慢\",\"flag\":\"公交车\"})\n",
    "# print(response)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "#LCEL 3，四个提示词一次执行，依据前面的提示词返回的内容，一步步的询问后面的提示词\n",
    "#如何将5个提示词用｜组合在一起？\n",
    "# prompt=ChatPromptTemplate.from_template(\"帮我规划一下从{start_place}到{end_place}的有哪几种出行方案\")\n",
    "# prompt2=ChatPromptTemplate.from_template(\"从{travel_mode}中找出最慢的出行方案是哪种？\")\n",
    "# prompt3=ChatPromptTemplate.from_template(\"从{travel_mode}中找出最快的出行方案是哪种？\")\n",
    "# prompt5=ChatPromptTemplate.from_template(\"{first_way}和{second_way}这两种出行方案的优点和缺点分别是什么？\")\n",
    "# # 先执行chain，得到含有travel_mode的输出\n",
    "# chain = prompt | llm | StrOutputParser()\n",
    "# travel_modes = chain.invoke({})\n",
    "\n",
    "# # 基于travel_modes的结果，执行prompt2和prompt3\n",
    "# first_way_chain = prompt2 | llm | StrOutputParser()\n",
    "# second_way_chain = prompt3 | llm | StrOutputParser()\n",
    "\n",
    "# first_way_result = first_way_chain.invoke({\"travel_mode\": travel_modes})\n",
    "# second_way_result = second_way_chain.invoke({\"travel_mode\": travel_modes})\n",
    "\n",
    "# # 最后执行prompt5，比较两种出行方案\n",
    "# final_chain = prompt5 | llm | StrOutputParser()\n",
    "# response = final_chain.invoke({\"first_way\": first_way_result, \"second_way\": second_way_result})\n",
    "# print(response)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "base",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python",
   "version": "3.11.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
